﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Extensil.Processor;
using Extensil.Processor.General;
using Extensil.Common;

namespace Extensil.Category.Automate
{
    [Extensil.Common.CategoryAttribute("Automated Task")]
    public partial class AutomatedTask :BaseCategory
    {
        ProgressUpdate pUpdate = new ProgressUpdate();
        TaskReader tr = new TaskReader();
        public static BackgroundWorker taskLeader = new BackgroundWorker();
        
        public AutomatedTask()
        {
            InitializeComponent();
            
            LoadAllTask();

            dgvTasks.RowLeave += new DataGridViewCellEventHandler(dgvTasks_RowLeave);

            pUpdate.TopLevel = false;
            pUpdate.Dock = DockStyle.Fill;
            pUpdate.FormBorderStyle = FormBorderStyle.None;
            splitContainer1.Panel2.Controls.Add(pUpdate);
            pUpdate.Show();
        }

        private void LoadAllTask()
        {
            DataGridViewTextBoxColumn column;

            foreach(KeyValuePair<string, AtributeInfo> tsk in Task.AttributeList)
            {
                switch(tsk.Value.PropType)
                {
                    case PropertyType.Combo:
                        DataGridViewComboBoxColumn cb = new DataGridViewComboBoxColumn();
                        cb.HeaderText = tsk.Key;
                        cb.Name = tsk.Key;
                        List<ComboPropertyParam> ds = (List<ComboPropertyParam>)tsk.Value.PropParam;
                        List<string> tBaseList = TaskFactory.GetSystemTaskHandlers();
                        foreach(string tBase in tBaseList)
                            ds.Add(new ComboPropertyParam(tBase, tBase));
                        cb.DataPropertyName = "Handler";
                        cb.DisplayMember = "Key";
                        cb.ValueMember = "Value";
                        cb.DataSource = ds;
                        dgvTasks.Columns.Add(cb);
                        break;
                    default:
                    case PropertyType.Text:
                        column = new DataGridViewTextBoxColumn();
                        column.Name = tsk.Key;
                        column.DataPropertyName = tsk.Key;
                        column.HeaderText = tsk.Key;
                        dgvTasks.Columns.Add(column);
                        break;
                }
            }

            dgvTasks.AutoGenerateColumns = false;

            BindingList<Task> tasks = new BindingList<Task>();
            foreach(Task t in tr.TaskList)
                tasks.Add(t);
            dgvTasks.DataSource = tasks;

        }
        private void btnStart_Click(object sender, EventArgs e)
        {
            taskLeader.WorkerReportsProgress = true;
            taskLeader.WorkerSupportsCancellation = true;
            taskLeader.DoWork += new DoWorkEventHandler(Start);
            taskLeader.ProgressChanged += new ProgressChangedEventHandler(TaskManager_Event);
            taskLeader.RunWorkerAsync();
        }
        private void TaskManager_Event(object sender, ProgressChangedEventArgs e)
        {
            TaskStatus ts = (TaskStatus)e.UserState;
            pUpdate.Add(ts, e.ProgressPercentage);
        }

        private void TaskWorker_Event(object sender, ProgressChangedEventArgs e)
        {
            AutomatedTask.taskLeader.ReportProgress(-1,
                new TaskStatus(StatusSource.Task, e.UserState.ToString(), e.ProgressPercentage));
        }
        private void Start(object sender, DoWorkEventArgs e)
        {
            for(int i = 0; i < tr.Count; i++)
            {
                TaskBase task = tr.Get(i);
                int prg = (i * 100) / tr.Count;
                AutomatedTask.taskLeader.ReportProgress(prg,
                    new TaskStatus(StatusSource.Main, tr.FormatLog("Executing task '" + task.Name + "'."), -1));
                task.Execute(TaskWorker_Event);
                AutomatedTask.taskLeader.ReportProgress(prg,
                    new TaskStatus(StatusSource.Main, tr.FormatLog("Task '" + task.Name + "' completed."), -1));

            }
            AutomatedTask.taskLeader.ReportProgress(100,
                new TaskStatus(StatusSource.Main, "All task completed successfully.", -1));
        }

        private void dgvTasks_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if(e.ColumnIndex >= 0 && e.RowIndex >= 0)
            {
                DataGridViewCell cell = dgvTasks[e.ColumnIndex, e.RowIndex];
                dgvTasks.CurrentCell = cell;

                cell.ReadOnly = false;
                dgvTasks.BeginEdit(true);
            }
        }

        private void dgvTasks_RowLeave(object sender, DataGridViewCellEventArgs e)
        {
            DataGridViewCell cell = dgvTasks[e.ColumnIndex, e.RowIndex];
            Task uTask = new Task();
            bool rowChanged = false;
            foreach(KeyValuePair<string, AtributeInfo> atr in Task.AttributeList)
            {
                if(e.RowIndex != dgvTasks.Rows.Count - 1 && atr.Value.IsRequired &&
                    (dgvTasks[atr.Key, e.RowIndex].EditedFormattedValue == null ||
                    dgvTasks[atr.Key, e.RowIndex].EditedFormattedValue.ToString() == ""))
                {
                    MessageBox.Show("Value of " + atr.Key + " can not be empty.");
                    dgvTasks.CurrentCell = dgvTasks[atr.Key, e.RowIndex];
                    return;
                }

                if(e.RowIndex == dgvTasks.Rows.Count - 1)
                {
                    typeof(Task).GetProperty(atr.Key).SetValue(uTask, dgvTasks[atr.Key, e.RowIndex].EditedFormattedValue, null);

                    if(dgvTasks.Rows[e.RowIndex].Cells[atr.Key].EditedFormattedValue.ToString() != "")
                        rowChanged = true;
                }
                else
                {
                    typeof(Task).GetProperty(atr.Key).SetValue(uTask, dgvTasks[atr.Key, e.RowIndex].EditedFormattedValue, null);

                    if(dgvTasks.Rows[e.RowIndex].Cells[atr.Key].EditedFormattedValue != dgvTasks.Rows[e.RowIndex].Cells[atr.Key].Value)
                        rowChanged = true;
                }

                if(rowChanged)
                {
                    if(e.RowIndex == dgvTasks.Rows.Count - 1)
                    {
                        tr.TaskList.AddNewTask(uTask);
                    }
                    else
                    {
                        tr.TaskList.EditTask(e.RowIndex, uTask);
                    }
                }
            }
        }

        private void dgvTasks_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            e.Cancel = true;
        }

        public override BaseSetting Setting
        {
            get
            {
                return new AutomateSettings();
            }
        }

        public override BaseHelp Help
        {
            get
            {
                return new AutomateHelp();
            }
        }
    }
}
